package uk.ac.lkl.common.util;



import javax.swing.event.ChangeListener;

import uk.ac.lkl.lpp.dirtyListener;


/**
 * A named property.
 * 
 * Properties can be listened to for change events.
 * 
 * @author Darren Pearce
 * @version $Revision$
 * @version $Date$
 * 
 */
public abstract class Property {

    /**
     * The name of this instance.
     * 
     */
    private String name;
        
    /**
     * The support for change listening for this instance.
     * 
     */
    private ChangeSupport changeSupport;


    /**
     * Create a new instance with the given name.
     * 
     * @param name
     *            the name of this instance
     */
    public Property(String name) {
        this.name = name;
        this.changeSupport = new ChangeSupport(this);
        
    }

    /**
     * Get the name of this instance.
     * 
     * @return the name of this instance
     * 
     */
    public String getName() {
        return name;
    }

    /**
     * Set the value of this instance.
     * 
     * If the property changes as a result, change listeners are
     * appropriately notified.
     * 
     * @param value
     *            the new value of this instance
     * 
     * @throws IllegalArgumentException
     *             if a problem occurred during value setting
     * 
     */
    public void setValue(String value) throws IllegalArgumentException {
        boolean changed = doSetValue(value);
        if (changed){
        	
        	fireStateChanged();
        	dirtyListener.setDirty();
        }
            
    }


    /**
     * Do the sub-class specific setting of this instance.
     * 
     * @param value
     *            the new value of this instance
     * @return <code>true</code> if the value was changed;
     *         <code>false</code> otherwise
     * 
     * @throws IllegalArgumentException
     *             if a problem occurred during value setting
     * 
     */
    protected abstract boolean doSetValue(String value)
            throws IllegalArgumentException;


    public abstract String getValue();


    public abstract String getType();


    private void fireStateChanged() {
        changeSupport.fireStateChanged();
       
    }


    public void addChangeListener(ChangeListener listener) {
        changeSupport.addListener(listener);
    }


    public void removeChangeListener(ChangeListener listener) {
        changeSupport.removeListener(listener);
    }
}
